package com.ttl.common.util;

import hibernate.util.HibernateUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.ttl.bc.ap.invoice.bean.BCAPInvoiceBean;
import com.ttl.bc.ap.invoice.bo.BCAPInvoiceDAO;
import com.ttl.bc.gl.trans.bean.BCTrans;
import com.ttl.bc.stock.request2.bean.BCStkIssue2;

public class Page {
	
	@SuppressWarnings("rawtypes")
	private	List resultList;
	private	int	maxEntriesPerPage;
	private	int currentPage;
	private	int	allElement;
	
	public Page() {
		this.allElement = 0;
	}
	public Page(Query query, int currentPage, int maxEntriesPerPage) {
		this.currentPage = currentPage;
		this.maxEntriesPerPage = maxEntriesPerPage;
		resultList = query.setFirstResult(currentPage*maxEntriesPerPage).setMaxResults(maxEntriesPerPage).list();
	}
	
	
	public boolean isNextPage() {
//		System.out.println("allElement="+allElement);
//		System.out.println("currentPage*maxEntriesPerPage = "+currentPage*maxEntriesPerPage);
		return allElement > currentPage*maxEntriesPerPage;
	}
	public boolean isPreviousPage() {
		return getCurrentPage() > 1;
	}
	public boolean isFirstPage() {
		return currentPage>1;//getAllElement()>0;
	}
	public boolean isLastPage() {
		return isNextPage();//getAllElement()>0;
	}
	
	@SuppressWarnings("rawtypes")
	public List getResultList() {
		return resultList;
	}	
	@SuppressWarnings("rawtypes")
	public void setResultList(List resultList) {
		this.resultList = resultList;
	}

	public int getMaxEntriesPerPage() {
		return maxEntriesPerPage;
	}
	public void setMaxEntriesPerPage(int maxEntriesPerPage) {
		this.maxEntriesPerPage = maxEntriesPerPage;
	}
	public int getCurrentPage() {
		return currentPage;
	}
	public void setCurrentPage(int currentPage) {
		this.currentPage = currentPage;
	}
	public int getAllElement() {
		return allElement;
	}
	public void setAllElement(int allElement) {
		this.allElement = allElement;
	}			
	
	public static void setPage(HttpServletRequest request, String hql) {
		
		int pageNumber = 1;
		int maxEntriesPerPage = 20;
		int lineNumber = 1;
		
		try {pageNumber = Integer.parseInt(request.getParameter("page"));} catch (Exception e) {}
		
		if(request.getParameter("maxEntriesPerPage")!=null){maxEntriesPerPage = Integer.parseInt(request.getParameter("maxEntriesPerPage"));}
		
		if(request.getParameter("lineNumber")!=null) {
			request.setAttribute("lineNumber", request.getParameter("lineNumber"));
		}else {
			request.setAttribute("lineNumber", lineNumber);
		}
		
		Page page = getHibernateScrollableResultsPage(hql, pageNumber, maxEntriesPerPage);
		
		setAttributeOfPage(request, maxEntriesPerPage, pageNumber, page);
		
	}	

	public static void setPageForInvoice(HttpServletRequest request, String hql) {
		
		int pageNumber = 1;
		int maxEntriesPerPage = 20;
		int lineNumber = 1;
		
		try {pageNumber = Integer.parseInt(request.getParameter("page"));} catch (Exception e) {}
		
		if(request.getParameter("maxEntriesPerPage")!=null){maxEntriesPerPage = Integer.parseInt(request.getParameter("maxEntriesPerPage"));}
		
		if(request.getParameter("lineNumber")!=null) {
			request.setAttribute("lineNumber", request.getParameter("lineNumber"));
		}else {
			request.setAttribute("lineNumber", lineNumber);
		}
		
		Page page = getHibernateScrollableResultsPage(hql, pageNumber, maxEntriesPerPage);
		
		String docNo = "";
		if(page.getResultList()!=null && !page.getResultList().isEmpty()) {
			for (int i = 0; i < page.getResultList().size(); i++) {
				BCAPInvoiceBean inv = (BCAPInvoiceBean)page.getResultList().get(i);
				//System.out.println(inv.getDocNo());
				docNo = docNo + "'"+inv.getDocNo()+"',";
			}
			docNo = docNo.substring(0, docNo.length()-1);
			System.out.println(docNo);
		}
		
		if(docNo.length()>0) {
			BCAPInvoiceDAO dao = new BCAPInvoiceDAO();
			List<BCTrans> glList = dao.find("FROM BCTrans WHERE docNo in ("+docNo+")");
			
			if(glList!=null && !glList.isEmpty()) {
				for (int i = 0; i < page.getResultList().size(); i++) {
					BCAPInvoiceBean inv = (BCAPInvoiceBean)page.getResultList().get(i);
					
					for (BCTrans bcTrans : glList) {
						if(inv.getDocNo().equals(bcTrans.getDocNo())) {
							inv.setHasInBCtrans(1);
						}
					}
				}
				
				for (int i = 0; i < page.getResultList().size(); i++) {
					BCAPInvoiceBean inv = (BCAPInvoiceBean)page.getResultList().get(i);
					if(inv.getHasInBCtrans()==null) {
						inv.setHasInBCtrans(0);
					}
				}				
			}else {
				for (int i = 0; i < page.getResultList().size(); i++) {
					BCAPInvoiceBean inv = (BCAPInvoiceBean)page.getResultList().get(i);
					if(inv.getHasInBCtrans()==null) {
						inv.setHasInBCtrans(0);
					}
				}				
			}
		}
		
		setAttributeOfPage(request, maxEntriesPerPage, pageNumber, page);
		
	}	
	
	private static void setAttributeOfPage(HttpServletRequest request,
			int maxEntriesPerPage, int pageNumber, Page page) {
		request.setAttribute("maxEntriesPerPage", maxEntriesPerPage);
		request.setAttribute("allElement", page.getAllElement());
		
		if (page.getAllElement()>0) {
			request.setAttribute("itemResults", page.getResultList());
			request.setAttribute("offset", (pageNumber-1)*maxEntriesPerPage);
			request.setAttribute("currentPage", page.getCurrentPage());
			
			if (page.isNextPage()==true) {	request.setAttribute("nextPage", page.getCurrentPage()+1);	}
			if (page.isPreviousPage()==true) {	request.setAttribute("previousPage", page.getCurrentPage()-1);	}
			if (page.isFirstPage()==true) {	request.setAttribute("firstPage", 1);	}
			if (page.isLastPage()==true && page.getMaxEntriesPerPage()!=0) {
				if (page.getAllElement()%page.getMaxEntriesPerPage()==0) {
					request.setAttribute("lastPage", page.getAllElement()/page.getMaxEntriesPerPage());
				}else {
					request.setAttribute("lastPage", page.getAllElement()/page.getMaxEntriesPerPage()+1);
				}
			}
		}		
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private static Page getHibernateScrollableResultsPage(String hql, int pageNumber, int maxEntriesPerPage) {
		Page page = new Page();
	
		ArrayList result = new ArrayList();
		
		long before = new Date().getTime();
		Session session = null;

		try {
			SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
			session = sessionFactory.openSession();
			session.beginTransaction();
			
			// ลำดับข้อมูลที่จะให้แสดงผล เช่น 0-100
			int offset = (pageNumber-1)*maxEntriesPerPage;
			
			Query q = session.createQuery(hql);
			
			ScrollableResults scr = q.scroll();
			// ตรวจสอบก่อนว่าค้นหาเจอหรือไม่ (ถ้าเจอจะได้ ค่า RowNumber ที่ rec สุดท้ายมากกว่า -1
			scr.last();
			
			if(scr.getRowNumber()>-1) {
				scr.first();
				scr.scroll(offset);
				
				int i=0;
				while (maxEntriesPerPage>i++) {
					result.add(scr.get(0));
					if(!scr.next()) {
						break;
					}					
				}
				scr.last();
				page.setAllElement(scr.getRowNumber()+1);
				page.setCurrentPage(pageNumber);
				page.setMaxEntriesPerPage(maxEntriesPerPage);
				page.setResultList(result);
			}
			session.getTransaction().commit();

			
		} catch (Exception e) {
			System.out.println(e.toString());
		}finally {
			session.close();
		}
		long after = new Date().getTime();
		double resultTime = (after-before)/1000d;
		System.out.println("resultTime: "+resultTime+" second");
		
		return page;
	}
	
	public static boolean showPage(HttpServletRequest request, String hql) {
		
		int pageNumber = 1;
		int maxEntriesPerPage = 20;
		int lineNumber = 1;
		
		try {pageNumber = Integer.parseInt(request.getParameter("page"));} catch (Exception e) {}
		
		if(request.getParameter("maxEntriesPerPage")!=null){maxEntriesPerPage = Integer.parseInt(request.getParameter("maxEntriesPerPage"));}
		
		if(request.getParameter("lineNumber")!=null) {
			request.setAttribute("lineNumber", request.getParameter("lineNumber"));
		}else {
			request.setAttribute("lineNumber", lineNumber);
		}
		
		Page page = getHibernateScrollableResultsPage(hql, pageNumber, maxEntriesPerPage);
		return getAttributeOfRequest(request, page);

	}
	
	private static boolean getAttributeOfRequest(HttpServletRequest request,
			Page page) {
		request.setAttribute("maxEntriesPerPage", page.getMaxEntriesPerPage());
		request.setAttribute("allElement", page.getAllElement());
		
		if (page!=null && page.getAllElement()>0) {
			request.setAttribute("itemResults", page.getResultList());
			request.setAttribute("offset", (page.getCurrentPage()-1)*page.getMaxEntriesPerPage());
			request.setAttribute("currentPage", page.getCurrentPage());
			
			if (page.isNextPage()==true) {	request.setAttribute("nextPage", page.getCurrentPage()+1);	}
			if (page.isPreviousPage()==true) {	request.setAttribute("previousPage", page.getCurrentPage()-1);	}
			if (page.isFirstPage()==true) {	request.setAttribute("firstPage", 1);	}
			if (page.isLastPage()==true && page.getMaxEntriesPerPage()!=0) {
				if (page.getAllElement()%page.getMaxEntriesPerPage()==0) {
					request.setAttribute("lastPage", page.getAllElement()/page.getMaxEntriesPerPage());
				}else {
					request.setAttribute("lastPage", page.getAllElement()/page.getMaxEntriesPerPage()+1);
				}
			}
			return true;
		}else {
			return false;
		}		
	}
	
	public static void setPageForBCStkIssue(HttpServletRequest request,
			String hql) {
 
		int pageNumber = 1;
		int maxEntriesPerPage = 20;
		int lineNumber = 1;
		
		try {pageNumber = Integer.parseInt(request.getParameter("page"));} catch (Exception e) {}
		
		if(request.getParameter("maxEntriesPerPage")!=null){maxEntriesPerPage = Integer.parseInt(request.getParameter("maxEntriesPerPage"));}
		
		if(request.getParameter("lineNumber")!=null) {
			request.setAttribute("lineNumber", request.getParameter("lineNumber"));
		}else {
			request.setAttribute("lineNumber", lineNumber);
		}
		
		Page page = getHibernateScrollableResultsPage(hql, pageNumber, maxEntriesPerPage);
		
		String docNo = "";
		if(page.getResultList()!=null && !page.getResultList().isEmpty()) {
			for (int i = 0; i < page.getResultList().size(); i++) {
				BCStkIssue2 inv = (BCStkIssue2)page.getResultList().get(i);
				//System.out.println(inv.getDocNo());
				docNo = docNo + "'"+inv.getDocNo()+"',";
			}
			docNo = docNo.substring(0, docNo.length()-1);
			System.out.println(docNo);
		}
		
		if(docNo.length()>0) {
			BCAPInvoiceDAO dao = new BCAPInvoiceDAO();
			List<BCTrans> glList = dao.find("FROM BCTrans WHERE docNo in ("+docNo+")");
			
			if(glList!=null && !glList.isEmpty()) {
				for (int i = 0; i < page.getResultList().size(); i++) {
					BCStkIssue2 inv = (BCStkIssue2)page.getResultList().get(i);
					
					for (BCTrans bcTrans : glList) {
						if(inv.getDocNo().equals(bcTrans.getDocNo())) {
							inv.setHasInBCtrans(1);
						}
					}
				}
				
				for (int i = 0; i < page.getResultList().size(); i++) {
					BCStkIssue2 inv = (BCStkIssue2)page.getResultList().get(i);
					if(inv.getHasInBCtrans()==null) {
						inv.setHasInBCtrans(0);
					}
				}				
			}else {
				for (int i = 0; i < page.getResultList().size(); i++) {
					BCStkIssue2 inv = (BCStkIssue2)page.getResultList().get(i);
					if(inv.getHasInBCtrans()==null) {
						inv.setHasInBCtrans(0);
					}
				}				
			}
		}
		
		setAttributeOfPage(request, maxEntriesPerPage, pageNumber, page);		
	}
	
}
